home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / _archvrs / unix / arc521.lha / arc / arcadd.c < prev    next >
C/C++ Source or Header  |  1989-08-08  |  10KB  |  372 lines

  1. /*
  2.  * $Header: arcadd.c,v 1.10 88/11/16 17:43:25 hyc Exp $
  3.  */
  4.  
  5. /*
  6.  * ARC - Archive utility - ARCADD
  7.  * 
  8.  * Version 3.40, created on 06/18/86 at 13:10:18
  9.  * 
  10.  * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  11.  * 
  12.  * By:  Thom Henderson
  13.  * 
  14.  * Description: This file contains the routines used to add files to an archive.
  15.  * 
  16.  * Language: Computer Innovations Optimizing C86
  17.  */
  18. #include <stdio.h>
  19. #include "arc.h"
  20. #if    MTS
  21. #include <mts.h>
  22. #endif
  23.  
  24. static    int    addfile();
  25. char    *strcpy();
  26. int    strcmp(), strlen(), free(), readhdr(), unlink();
  27. #if    UNIX
  28. int    izadir();
  29. #endif
  30. void    writehdr(), filecopy(), getstamp();
  31. void    pack(), closearc(), openarc(), abort();
  32.  
  33. void
  34. addarc(num, arg, move, update, fresh)        /* add files to archive */
  35.     int             num;    /* number of arguments */
  36.     char           *arg[];    /* pointers to arguments */
  37. int             move;        /* true if moving file */
  38. int             update;        /* true if updating */
  39. int             fresh;        /* true if freshening */
  40. {
  41.     char           *d, *dir();    /* directory junk */
  42.     char            buf[STRLEN];    /* pathname buffer */
  43.     char          **path;    /* pointer to pointers to paths */
  44.     char          **name;    /* pointer to pointers to names */
  45.     int             nfiles = 0;    /* number of files in lists */
  46.     int             notemp;    /* true until a template works */
  47.     int             nowork = 1;    /* true until files are added */
  48.     char           *i, *rindex();    /* string indexing junk */
  49.     char           *malloc(), *realloc();    /* memory allocators */
  50.     int             n;    /* index */
  51. #if    MSDOS
  52.     unsigned int    coreleft();    /* remaining memory reporter */
  53. #endif
  54.     int        addbunch();
  55.  
  56.     if (num < 1) {        /* if no files named */
  57.         num = 1;    /* then fake one */
  58. #if    DOS
  59.         arg[0] = "*.*";    /* add everything */
  60. #endif
  61. #if    UNIX
  62.         arg[0] = "*";
  63. #endif
  64. #if    MTS
  65.         arg[0] = "?";
  66. #endif
  67.     }
  68.     path = (char **) malloc(sizeof(char **));
  69.     name = (char **) malloc(sizeof(char **));
  70.  
  71.  
  72.     for (n = 0; n < num; n++) {    /* for each template supplied */
  73.         strcpy(buf, arg[n]);    /* get ready to fix path */
  74. #if    !MTS
  75.         if (!(i = rindex(buf, '\\')))
  76.             if (!(i = rindex(buf, '/')))
  77.                 if (!(i = rindex(buf, ':')))
  78.                     i = buf - 1;
  79. #else
  80.         if (!(i = rindex(buf, sepchr[0])))
  81.             if (buf[0] != tmpchr[0])
  82.                 i = buf - 1;
  83.             else
  84.                 i = buf;
  85. #endif
  86.         i++;        /* pointer to where name goes */
  87.  
  88.         notemp = 1;    /* reset files flag */
  89.         for (d = dir(arg[n]); d; d = dir(NULL)) {
  90.             notemp = 0;    /* template is giving results */
  91.             nfiles++;    /* add each matching file */
  92.             path = (char **) realloc(path, nfiles * sizeof(char **));
  93.             name = (char **) realloc(name, nfiles * sizeof(char **));
  94.             strcpy(i, d);    /* put name in path */
  95.             path[nfiles - 1] = malloc(strlen(buf) + 1);
  96.             strcpy(path[nfiles - 1], buf);
  97.             name[nfiles - 1] = d;    /* save name */
  98. #if    MSDOS
  99.             if (coreleft() < 5120) {
  100.                 nfiles = addbunch(nfiles, path, name, move, update, fresh);
  101.                 nowork = nowork && !nfiles;
  102.                 while (nfiles) {
  103.                     free(path[--nfiles]);
  104.                     free(name[nfiles]);
  105.                 }
  106.                 free(path);
  107.                 free(name);
  108.                 path = name = NULL;
  109.             }
  110. #endif
  111.         }
  112.         if (notemp && warn)
  113.             printf("No files match: %s\n", arg[n]);
  114.     }
  115.  
  116.     if (nfiles) {
  117.         nfiles = addbunch(nfiles, path, name, move, update, fresh);
  118.         nowork = nowork && !nfiles;
  119.         while (nfiles) {
  120.             free(path[--nfiles]);
  121.             free(name[nfiles]);
  122.         }
  123.         free(path);
  124.         free(name);
  125.     }
  126.     if (nowork && warn)
  127.         printf("No files were added.\n");
  128. }
  129.  
  130. int
  131. addbunch(nfiles, path, name, move, update, fresh)    /* add a bunch of files */
  132.     int             nfiles;    /* number of files to add */
  133.     char          **path;    /* pointers to pathnames */
  134.     char          **name;    /* pointers to filenames */
  135.     int             move;    /* true if moving file */
  136.     int             update;    /* true if updating */
  137.     int             fresh;    /* true if freshening */
  138. {
  139.     int             m, n;    /* indices */
  140.     char           *d;    /* swap pointer */
  141.     struct heads    hdr;    /* file header data storage */
  142.  
  143.     for (n = 0; n < nfiles - 1; n++) {    /* sort the list of names */
  144.         for (m = n + 1; m < nfiles; m++) {
  145.             if (strcmp(name[n], name[m]) > 0) {
  146.                 d = path[n];
  147.                 path[n] = path[m];
  148.                 path[m] = d;
  149.                 d = name[n];
  150.                 name[n] = name[m];
  151.                 name[m] = d;
  152.             }
  153.         }
  154.     }
  155.  
  156.     for (n = 0; n < nfiles - 1;) {    /* consolidate the list of names */
  157.         if (!strcmp(path[n], path[n + 1])    /* if duplicate names */
  158.             ||!strcmp(path[n], arcname)    /* or this archive */
  159. #if    UNIX
  160.             ||izadir(path[n])    /* or a directory */
  161. #endif
  162.             ||!strcmp(path[n], newname)    /* or the new version */
  163.             ||!strcmp(path[n], bakname)) {    /* or its backup */
  164.             free(path[n]);    /* then forget the file */
  165.             free(name[n]);
  166.             for (m = n; m < nfiles - 1; m++) {
  167.                 path[m] = path[m + 1];
  168.                 name[m] = name[m + 1];
  169.             }
  170.             nfiles--;
  171.         } else
  172.             n++;    /* else test the next one */
  173.     }
  174.  
  175.     if (!strcmp(path[n], arcname)    /* special check for last file */
  176.         ||!strcmp(path[n], newname)    /* courtesy of Rick Moore */
  177. #if    UNIX
  178.         ||izadir(path[n])
  179. #endif
  180.         || !strcmp(path[n], bakname)) {
  181.         free(path[n]);
  182.         free(name[n]);
  183.         nfiles--;
  184.     }
  185.     if (!nfiles)        /* make sure we got some */
  186.         return 0;
  187.  
  188.     for (n = 0; n < nfiles - 1; n++) {    /* watch out for duplicate
  189.                          * names */
  190.         if (!strcmp(name[n], name[n + 1]))
  191.             abort("Duplicate filenames:\n  %s\n  %s", path[n], path[n + 1]);
  192.     }
  193.     openarc(1);        /* open archive for changes */
  194.  
  195.     for (n = 0; n < nfiles;) { /* add each file in the list */
  196.         if (addfile(path[n], name[n], update, fresh) < 0) {
  197.             free(path[n]);        /* remove this name if */
  198.             free(name[n]);        /* it wasn't added */
  199.             for (m = n; m < nfiles-1 ; m++) {
  200.                 path[m] = path[m+1];
  201.                 name[m] = name[m+1];
  202.             }
  203.             nfiles--;
  204.         } else n++;
  205.     }
  206.  
  207.     /* now we must copy over all files that follow our additions */
  208.  
  209.     while (readhdr(&hdr, arc)) {    /* while more entries to copy */
  210.         writehdr(&hdr, new);
  211.         filecopy(arc, new, hdr.size);
  212.     }
  213.     hdrver = 0;        /* archive EOF type */
  214.     writehdr(&hdr, new);    /* write out our end marker */
  215.     closearc(1);        /* close archive after changes */
  216.  
  217.     if (move) {        /* if this was a move */
  218.         for (n = 0; n < nfiles; n++) {    /* then delete each file
  219.                          * added */
  220.             if (unlink(path[n]) && warn) {
  221.                 printf("Cannot unsave %s\n", path[n]);
  222.                 nerrs++;
  223.             }
  224.         }
  225.     }
  226.     return nfiles;        /* say how many were added */
  227. }
  228.  
  229. static          int
  230. addfile(path, name, update, fresh)    /* add named file to archive */
  231.     char           *path;    /* path name of file to add */
  232.     char           *name;    /* name of file to add */
  233.     int             update;    /* true if updating */
  234.     int             fresh;    /* true if freshening */
  235. {
  236.     struct heads    nhdr;    /* data regarding the new file */
  237.     struct heads    ohdr;    /* data regarding an old file */
  238.     FILE           *f, *fopen();    /* file to add, opener */
  239.     long            starts, ftell();    /* file locations */
  240.     int             upd = 0;/* true if replacing an entry */
  241.  
  242. #if    !MTS
  243.     if (!(f = fopen(path, OPEN_R)))
  244. #else
  245.     if (image)
  246.         f = fopen(path, "rb");
  247.     else
  248.         f = fopen(path, "r");
  249.     if (!f)
  250. #endif
  251.     {
  252.         if (warn) {
  253.             printf("Cannot read file: %s\n", path);
  254.             nerrs++;
  255.         }
  256.         return(-1);
  257.     }
  258. #if    !DOS
  259.     if (strlen(name) >= FNLEN) {
  260.         if (warn) {
  261.             char    buf[STRLEN];
  262.             printf("WARNING: File %s name too long!\n", name);
  263.             name[FNLEN-1]='\0';
  264.             while(1) {
  265.                 printf("  Truncate to %s (y/n)? ", name);
  266.                 fflush(stdout);
  267.                 fgets(buf, STRLEN, stdin);
  268.                 *buf = toupper(*buf);
  269.                 if (*buf == 'Y' || *buf == 'N')
  270.                     break;
  271.             }
  272.             if (*buf == 'N') {
  273.                 printf("Skipping...\n");
  274.                 fclose(f);
  275.                 return(-1);
  276.             }
  277.         }
  278.         else {
  279.             if (note)
  280.                 printf("Skipping file: %s - name too long.\n",
  281.                     name);
  282.             fclose(f);
  283.             return(-1);
  284.         }
  285.     }
  286. #endif
  287.     strcpy(nhdr.name, name);/* save name */
  288.     nhdr.size = 0;        /* clear out size storage */
  289.     nhdr.crc = 0;        /* clear out CRC check storage */
  290. #if    !MTS
  291.     getstamp(f, &nhdr.date, &nhdr.time);
  292. #else
  293.     {
  294.     char *buffer, *malloc();
  295.     int    inlen;
  296.     struct    GDDSECT    *region;
  297.  
  298.     region=gdinfo(f->_fd._fdub);
  299.     inlen=region->GDINLEN;
  300.     buffer=malloc(inlen);    /* maximum line length */
  301.     setbuf(f,buffer);        
  302.     f->_bufsiz=inlen;        
  303.     f->_mods|=_NOIC;    /* Don't do "$continue with" */
  304.     f->_mods&=~_IC;        /* turn it off, if set... */
  305.     }
  306.     getstamp(path, &nhdr.date, &nhdr.time);
  307. #endif
  308.  
  309.     /* position archive to spot for new file */
  310.  
  311.     if (arc) {        /* if adding to existing archive */
  312.         starts = ftell(arc);    /* where are we? */
  313.         while (readhdr(&ohdr, arc)) {    /* while more files to check */
  314.             if (!strcmp(ohdr.name, nhdr.name)) {
  315.                 upd = 1;    /* replace existing entry */
  316.                 if (update || fresh) {    /* if updating or
  317.                              * freshening */
  318.                     if (nhdr.date < ohdr.date
  319.                         || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) {
  320.                         fseek(arc, starts, 0);
  321.                         fclose(f);
  322.                         return(0);/* skip if !newer */
  323.                     }
  324.                 }
  325.             }
  326.             if (strcmp(ohdr.name, nhdr.name) >= 0)
  327.                 break;    /* found our spot */
  328.  
  329.             writehdr(&ohdr, new);    /* entry preceeds update;
  330.                          * keep it */
  331.             filecopy(arc, new, ohdr.size);
  332.             starts = ftell(arc);    /* now where are we? */
  333.         }
  334.  
  335.         if (upd) {    /* if an update */
  336.             if (note) {
  337.                 printf("Updating file: %-12s  ", name);
  338.                 fflush(stdout);
  339.             }
  340.             fseek(arc, ohdr.size, 1);
  341.         } else if (fresh) {    /* else if freshening */
  342.             fseek(arc, starts, 0);    /* then do not add files */
  343.             fclose(f);
  344.             return(0);
  345.         } else {    /* else adding a new file */
  346.             if (note) {
  347.                 printf("Adding file:   %-12s  ", name);
  348.                 fflush(stdout);
  349.             }
  350.             fseek(arc, starts, 0);    /* reset for next time */
  351.         }
  352.     } else {        /* no existing archive */
  353.         if (fresh) {    /* cannot freshen nothing */
  354.             fclose(f);
  355.             return(0);
  356.         } else if (note) {    /* else adding a file */
  357.             printf("Adding file:   %-12s  ", name);
  358.             fflush(stdout);
  359.         }
  360.     }
  361.  
  362.     starts = ftell(new);    /* note where header goes */
  363.     hdrver = ARCVER;        /* anything but end marker */
  364.     writehdr(&nhdr, new);    /* write out header skeleton */
  365.     pack(f, new, &nhdr);    /* pack file into archive */
  366.     fseek(new, starts, 0);    /* move back to header skeleton */
  367.     writehdr(&nhdr, new);    /* write out real header */
  368.     fseek(new, nhdr.size, 1);    /* skip over data to next header */
  369.     fclose(f);        /* all done with the file */
  370.     return(0);
  371. }
  372.